from django.shortcuts import render
from django.http import HttpResponse, Http404
from django.db.models import Q
from rest_framework import viewsets, status, permissions, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from django_filters.rest_framework import DjangoFilterBackend
from django_filters import FilterSet, CharFilter, ModelChoiceFilter
from django.contrib.auth import get_user_model

from .models import Project, ProjectAttachment
from .serializers import (
    ProjectSerializer, CreateProjectSerializer, UpdateProjectSerializer,
    ProjectAttachmentSerializer, AttachmentUploadSerializer
)
from accounts.models import Laboratory

User = get_user_model()


class ProjectFilter(FilterSet):
    """项目过滤器"""
    status = CharFilter(field_name='status', lookup_expr='exact')
    crop_type = CharFilter(field_name='crop_type', lookup_expr='icontains')
    laboratory = ModelChoiceFilter(queryset=Laboratory.objects.all())
    
    class Meta:
        model = Project
        fields = ['status', 'crop_type', 'laboratory']


class ProjectViewSet(viewsets.ModelViewSet):
    """
    项目管理视图集
    提供项目的完整CRUD操作，包括附件管理功能
    """
    
    queryset = Project.objects.select_related(
        'laboratory', 'laboratory__institution'
    ).prefetch_related('attachments')
    
    serializer_class = ProjectSerializer
    permission_classes = [permissions.IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser, JSONParser]
    
    # 过滤和搜索配置
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_class = ProjectFilter
    search_fields = ['name', 'description', 'location']
    ordering_fields = ['created_at', 'start_date', 'name']
    ordering = ['-created_at']
    
    def get_queryset(self):
        """
        根据用户权限过滤项目列表
        实验室管理员可以看到所有项目，实验室成员只能看到本实验室的项目
        """
        user = self.request.user
        queryset = super().get_queryset()
        
        # 超级用户可以看到所有项目
        if user.is_superuser:
            return queryset
        
        # 实验室管理员和成员都可以看到本实验室的所有项目
        if user.laboratory:
            return queryset.filter(laboratory=user.laboratory)
        
        # 其他情况返回空查询集
        return queryset.none()
    
    def get_serializer_class(self):
        """
        根据不同操作返回对应的序列化器
        """
        if self.action == 'create':
            return CreateProjectSerializer
        elif self.action in ['update', 'partial_update']:
            return UpdateProjectSerializer
        return ProjectSerializer
    
    def perform_create(self, serializer):
        """
        创建项目时设置实验室
        """
        user = self.request.user
        
        # 检查用户权限
        if user.user_type != 'laboratory':
            raise PermissionError("只有实验室管理员可以创建项目")
        
        # 保存项目
        project = serializer.save()
    
    def perform_update(self, serializer):
        """
        更新项目时检查权限
        """
        user = self.request.user
        project = serializer.instance
        
        # 检查用户权限
        if not self._can_edit_project(user, project):
            raise PermissionError("您没有权限编辑此项目")
        
        serializer.save()
    
    def perform_destroy(self, instance):
        """
        删除项目时检查权限
        """
        user = self.request.user
        
        if not self._can_edit_project(user, instance):
            raise PermissionError("您没有权限删除此项目")
        
        instance.delete()
    
    def _can_edit_project(self, user, project):
        """
        检查用户是否可以编辑项目
        """
        if user.is_superuser:
            return True
        
        if user.user_type == 'laboratory':
            # 实验室管理员可以编辑本实验室的项目
            return project.laboratory == user.laboratory
        
        return False
    
    def list(self, request, *args, **kwargs):
        """
        获取项目列表
        """
        queryset = self.filter_queryset(self.get_queryset())
        
        # 分页
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            paginated_response = self.get_paginated_response(serializer.data)
            
            # 自定义响应格式
            return Response({
                'message': '获取项目列表成功',
                'projects': paginated_response.data['results'],
                'total': paginated_response.data['count'],
                'page': request.GET.get('page', 1),
                'pageSize': self.paginator.page_size
            })
        
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            'message': '获取项目列表成功',
            'projects': serializer.data,
            'total': len(serializer.data),
            'page': 1,
            'pageSize': len(serializer.data)
        })
    
    def create(self, request, *args, **kwargs):
        """
        创建新项目
        """
        try:
            print(f"接收到的数据: {request.data}")
            serializer = self.get_serializer(data=request.data)
            print(f"使用的序列化器: {serializer.__class__.__name__}")
            
            if not serializer.is_valid():
                print(f"验证错误: {serializer.errors}")
                return Response({
                    'message': '数据验证失败',
                    'errors': serializer.errors
                }, status=status.HTTP_400_BAD_REQUEST)
            
            self.perform_create(serializer)
            
            # 返回完整的项目信息
            project_serializer = ProjectSerializer(
                serializer.instance, 
                context={'request': request}
            )
            
            return Response({
                'message': '项目创建成功',
                'project': project_serializer.data
            }, status=status.HTTP_201_CREATED)
            
        except PermissionError as e:
            print(f"权限错误: {str(e)}")
            return Response({
                'message': str(e)
            }, status=status.HTTP_403_FORBIDDEN)
        except Exception as e:
            print(f"创建项目时发生错误: {str(e)}")
            import traceback
            traceback.print_exc()
            return Response({
                'message': f'创建项目失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def retrieve(self, request, *args, **kwargs):
        """
        获取项目详情
        """
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        
        return Response({
            'message': '获取项目详情成功',
            'project': serializer.data
        })
    
    def update(self, request, *args, **kwargs):
        """
        更新项目
        """
        try:
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
            
            # 返回完整的项目信息
            project_serializer = ProjectSerializer(
                serializer.instance, 
                context={'request': request}
            )
            
            return Response({
                'message': '项目更新成功',
                'project': project_serializer.data
            })
            
        except PermissionError as e:
            return Response({
                'message': str(e)
            }, status=status.HTTP_403_FORBIDDEN)
    
    def destroy(self, request, *args, **kwargs):
        """
        删除项目
        """
        try:
            instance = self.get_object()
            self.perform_destroy(instance)
            
            return Response({
                'message': '项目删除成功'
            }, status=status.HTTP_200_OK)
            
        except PermissionError as e:
            return Response({
                'message': str(e)
            }, status=status.HTTP_403_FORBIDDEN)
    
    @action(detail=True, methods=['patch'])
    def update_status(self, request, pk=None):
        """
        更新项目状态
        """
        try:
            project = self.get_object()
            
            if not self._can_edit_project(request.user, project):
                return Response({
                    'message': '您没有权限更新此项目状态'
                }, status=status.HTTP_403_FORBIDDEN)
            
            new_status = request.data.get('status')
            if not new_status:
                return Response({
                    'message': '请提供新的项目状态'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 验证状态值
            valid_statuses = dict(Project.STATUS_CHOICES).keys()
            if new_status not in valid_statuses:
                return Response({
                    'message': f'无效的项目状态：{new_status}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            project.status = new_status
            project.save()
            
            serializer = ProjectSerializer(project, context={'request': request})
            return Response({
                'message': '项目状态更新成功',
                'project': serializer.data
            })
            
        except Exception as e:
            return Response({
                'message': f'更新项目状态失败：{str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(detail=True, methods=['post'], parser_classes=[MultiPartParser, FormParser])
    def attachments(self, request, pk=None):
        """
        上传项目附件
        """
        try:
            project = self.get_object()
            
            if not self._can_edit_project(request.user, project):
                return Response({
                    'message': '您没有权限上传附件到此项目'
                }, status=status.HTTP_403_FORBIDDEN)
            
            serializer = AttachmentUploadSerializer(
                data=request.data,
                context={'project': project, 'request': request}
            )
            
            if serializer.is_valid():
                attachments = serializer.save()
                attachment_data = ProjectAttachmentSerializer(
                    attachments, many=True, context={'request': request}
                ).data
                
                return Response({
                    'message': '附件上传成功',
                    'attachments': attachment_data
                }, status=status.HTTP_201_CREATED)
            
            return Response({
                'message': '附件上传失败',
                'errors': serializer.errors
            }, status=status.HTTP_400_BAD_REQUEST)
            
        except Exception as e:
            return Response({
                'message': f'附件上传失败：{str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(detail=True, methods=['delete'], url_path='attachments/(?P<attachment_id>[^/.]+)')
    def delete_attachment(self, request, pk=None, attachment_id=None):
        """
        删除项目附件
        """
        try:
            project = self.get_object()
            
            if not self._can_edit_project(request.user, project):
                return Response({
                    'message': '您没有权限删除此项目的附件'
                }, status=status.HTTP_403_FORBIDDEN)
            
            try:
                attachment = project.attachments.get(id=attachment_id)
            except ProjectAttachment.DoesNotExist:
                return Response({
                    'message': '附件不存在'
                }, status=status.HTTP_404_NOT_FOUND)
            
            # 删除文件和数据库记录
            if attachment.file:
                attachment.file.delete()
            attachment.delete()
            
            return Response({
                'message': '附件删除成功'
            })
            
        except Exception as e:
            return Response({
                'message': f'附件删除失败：{str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(detail=True, methods=['get'], url_path='attachments/(?P<attachment_id>[^/.]+)/download')
    def download_attachment(self, request, pk=None, attachment_id=None):
        """
        下载项目附件
        """
        try:
            project = self.get_object()
            
            # 检查用户是否有权限访问此项目
            user_projects = self.get_queryset()
            if not user_projects.filter(id=project.id).exists():
                return Response({
                    'message': '您没有权限访问此项目的附件'
                }, status=status.HTTP_403_FORBIDDEN)
            
            try:
                attachment = project.attachments.get(id=attachment_id)
            except ProjectAttachment.DoesNotExist:
                raise Http404('附件不存在')
            
            if not attachment.file:
                return Response({
                    'message': '文件不存在'
                }, status=status.HTTP_404_NOT_FOUND)
            
            # 返回文件响应
            response = HttpResponse(
                attachment.file.read(),
                content_type=attachment.content_type
            )
            response['Content-Disposition'] = f'attachment; filename="{attachment.name}"'
            response['Content-Length'] = attachment.size
            
            return response
            
        except Http404:
            return Response({
                'message': '附件不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({
                'message': f'文件下载失败：{str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
